--~ do
--~ 	local class = select(2, UnitClass"player")
--~ 	if class ~= "WARRIOR" and class ~= "DEATHKNIGHT" then return end
--~ end

local unit = "player"
-- health bar
local health = CreateFrame("Statusbar", nil, UIParent)
function health:UpdateUnit()
end

health:SetScript("OnUpdate", function (self)
	local currValue = UnitHealth(unit)
	if currValue ~= self.currValue then
		self:SetValue(currValue)
		self.currValue = currValue
		self:UpdateText()
	end
end)
health:SetOrientation"HORIZONTAL"
local t = health:CreateFontString(nil, "OVERLAY")
t:SetAllPoints()
t:SetFontObject(GameFontHighlightLarge)
health.text = t
function health:UpdateText()
	self.text:SetFormattedText("%d / %d", self.currValue, self.maxValue)
end
local t = health:CreateTexture(nil, "BACKGROUND")
t:SetAllPoints()
t:SetTexture(0,0,0,0.5)
health.background = t
health:Hide()
health:SetSize(250, 24)
health:SetPoint("CENTER", 0, -180)
health:SetScript("OnEvent", function (self, ...)
	local lsm = LibStub("LibSharedMedia-3.0", true)
	if lsm then
		t = lsm:Fetch("statusbar", "Otravi")
		self:SetStatusBarTexture(t)
--~ 		self.background:SetTexture(t)
	end
	self:SetStatusBarColor(0.0, 1.0, 0.0)
	self.currValue = UnitHealth(unit)
	self.maxValue = UnitHealthMax(unit)
	self:SetMinMaxValues(0, self.maxValue);
	self:UnregisterEvent"PLAYER_LOGIN"
	self:RegisterEvent"UNIT_MAXHEALTH"
	self:RegisterEvent"UNIT_ENTERED_VEHICLE"
	self:RegisterEvent"UNIT_EXITED_VEHICLE"
	self:SetScript("OnEvent", function (self, event, unit_)
		if unit_ ~= "player" and unit_ ~= unit then return end
		if UnitHasVehicleUI"player" then
			unit = "vehicle"
			self:SetStatusBarColor(0.4, 1.0, 0.0)
		else
			unit = "player"
			self:SetStatusBarColor(0.0, 1.0, 0.0)
		end
		local maxValue = UnitHealthMax(unit)
		if maxValue ~= self.maxValue then
			self.maxValue = maxValue
			self:SetMinMaxValues(0, maxValue)
			self:UpdateText()
		end
	end)
	local lhc = LibStub("LibHealComm-4.0", true)
	if lhc then
		local guid = UnitGUID(unit)
		local flags = lhc.ALL_HEALS
		function self:UpdateText()
			local healed = lhc:GetHealAmount(guid, flags, 2)
			local currValue, maxValue = self.currValue, self.maxValue
			if healed then
				healed = healed * lhc:GetHealModifier(guid)
				self.text:SetFormattedText("%d (+ %d) / %d", currValue, healed, maxValue)
			else
				self.text:SetFormattedText("%d / %d", currValue, maxValue)
			end
		end
		function self:UpdateHeal()
			self:UpdateText()
		end
		lhc.RegisterCallback(self, "HealComm_HealStarted", "UpdateHeal")
		lhc.RegisterCallback(self, "HealComm_HealStarted", "UpdateHeal")
		lhc.RegisterCallback(self, "HealComm_HealStarted", "UpdateHeal")
		lhc.RegisterCallback(self, "HealComm_HealStarted", "UpdateHeal")
	end
	self:UpdateText()
	self:Show()
--~ 	print("lsm", lsm, "lhc", lhc)
end)
health:RegisterEvent"PLAYER_LOGIN"

-- power bar
local rage = CreateFrame("Statusbar", nil, UIParent)
rage:SetScript("OnUpdate", function (self)
	local currValue = UnitPower(unit, self.powerType)
	if currValue ~= self.currValue then
		self:SetValue(currValue)
		self.currValue = currValue
		self:UpdateText()
	end
end)
rage:SetOrientation"HORIZONTAL"
local t = rage:CreateFontString(nil, "OVERLAY")
t:SetAllPoints()
t:SetFontObject(GameFontHighlightSmall)
rage.text = t
function rage:UpdateText()
	local currValue, maxValue = self.currValue, self.maxValue
	if maxValue == 100 then
		self.text:SetText(("%d"):format(currValue))
	else
		self.text:SetText(("%d / %d"):format(currValue, maxValue))
	end
end
rage:SetSize(250, 8)
rage:SetPoint("TOP", health, "BOTTOM", 0, -1)

local function set_power_type_color(self, powerType, powerName, altR, altG, altB)
	local color = PowerBarColor[powerName]
	if color then
		self:SetStatusBarColor(color.r, color.g, color.b)
	else
		self:SetStatusBarColor(altR, altG, altB)
	end
	return powerType
end

rage:SetScript("OnEvent", function (self, ...)
	local lsm = LibStub("LibSharedMedia-3.0", true)
	if lsm then self:SetStatusBarTexture(lsm:Fetch("statusbar", "Otravi")) end
	local powerType = set_power_type_color(self, UnitPowerType(unit))
	self:UnregisterEvent"PLAYER_LOGIN"
	self:RegisterEvent"UNIT_MAXMANA"
	self:RegisterEvent"UNIT_MAXRAGE"
	self:RegisterEvent"UNIT_MAXFOCUS"
	self:RegisterEvent"UNIT_MAXENERGY"
	self:RegisterEvent"UNIT_MAXHAPPINESS"
	self:RegisterEvent"UNIT_MAXRUNIC_POWER"
	self:RegisterEvent"UNIT_DISPLAYPOWER"
	self:RegisterEvent"UNIT_ENTERED_VEHICLE"
	self:RegisterEvent"UNIT_EXITED_VEHICLE"
	self.powerType = powerType
	self.maxValue = UnitPowerMax(unit, powerType)
	self.currValue = UnitPower(unit, powerType)
	self:SetMinMaxValues(0, self.maxValue)
	self.OnEvent = function (self, event, unit_)
		if not event or (event == "UNIT_DISPLAYPOWER" and unit_ == unit) then
			local powerType = set_power_type_color(self, UnitPowerType(unit))
			self.powerType = powerType
		elseif unit_ == unit then
			local powerType = self.powerType
			local maxValue = UnitPowerMax(unit, powerType)
			if maxValue == 0 then
				self:Hide()
			else
				self:Show()
			end
			self.currValue = UnitPower(unit, powerType)
			self.maxValue = maxValue
			self:SetMinMaxValues(0, maxValue)
			self:UpdateText()
		end
	end
	self:SetScript("OnEvent", self.OnEvent)
	self:UpdateText()
	self:Show()
end)
rage:Hide()
rage:RegisterEvent"PLAYER_LOGIN"


local combo = CreateFrame("Frame", nil, UIParent)
combo:ClearAllPoints()
combo:SetWidth(16*5+8)
combo:SetHeight(24)

combo.points = {}
for i = 1, 5 do
	local t = combo:CreateTexture(nil, "BACKGROUND")
	t:SetTexture("Interface\\ComboFrame\\ComboPoint")
	combo.points[i] = t
	t:ClearAllPoints()
	t:SetWidth(12)
	t:SetHeight(16)
	t:SetTexCoord(0, 0.375, 0, 1)
	t:SetPoint("BOTTOMLEFT", i * 16 - 8, 0)
	t:Show()
	local highlight = combo:CreateTexture(nil, "ARTWORK")
	t.highlight = highlight
	highlight:SetTexture"Interface\\ComboFrame\\ComboPoint"
	highlight:ClearAllPoints()
	highlight:SetWidth(8)
	highlight:SetHeight(16)
	highlight:SetTexCoord(0.375, 0.5625, 0, 1)
	highlight:SetPoint("CENTER", t)
	highlight:Hide()
	local shine =  combo:CreateTexture(nil, "OVERLAY")
	shine:SetTexture"Interface\\ComboFrame\\ComboPoint"
	shine:SetBlendMode"ADD"
	shine:ClearAllPoints()
	shine:SetWidth(14)
	shine:SetHeight(16)
	shine:SetTexCoord(0.5625, 1, 0, 1)
	shine:SetPoint("CENTER", t)
	shine:Hide()
	
	highlight.anim = highlight:CreateAnimationGroup()
	local fadein = highlight.anim:CreateAnimation"Alpha"
	fadein:SetStartDelay(0)
	fadein:SetEndDelay(0)
	fadein:SetSmoothing"IN_OUT"
	fadein:SetOrder(1)
	fadein:SetMaxFramerate(30)
	fadein:SetChange(1)
	fadein:SetDuration(.4)
	highlight.anim:SetScript("OnPlay", function (self)
		highlight:Show()
		highlight:SetAlpha(0)
	end)
	highlight.anim:SetScript("OnFinished", function (self)
		highlight:SetAlpha(1)
		shine.anim:Play()
	end)
	shine.anim = shine:CreateAnimationGroup()
	local fadein = shine.anim:CreateAnimation"Alpha"
	fadein:SetStartDelay(0)
	fadein:SetEndDelay(0)
	fadein:SetSmoothing"IN_OUT"
	fadein:SetOrder(1)
	fadein:SetMaxFramerate(30)
	fadein:SetChange(1)
	fadein:SetDuration(.3)
	local fadeout = shine.anim:CreateAnimation"Alpha"
	fadeout:SetStartDelay(0)
	fadeout:SetEndDelay(0)
	fadeout:SetSmoothing"IN_OUT"
	fadeout:SetOrder(2)
	fadeout:SetMaxFramerate(30)
	fadeout:SetChange(-1)
	fadeout:SetDuration(.3)
	shine.anim:SetScript("OnPlay", function (self)
		shine:Show()
		shine:SetAlpha(0)
	end)
	shine.anim:SetScript("OnFinished", function (self)
		shine:SetAlpha(0)
		shine:Hide()
	end)
end

combo:SetPoint("TOP", rage, "BOTTOM", 0, -1)
combo:Hide()

combo:SetScript("OnEvent", function (self, event, unit_)
	if event ~= "TARGET_CHANGED" or unit_ ~= "player" and unit_ ~= unit then
		local cb = GetComboPoints(unit, "target")
		if not cb or cb == 0 then
			self:Hide()
		else
			self:Show()
			for i = 1, 5 do
				if cb >= i then
					local highlight = self.points[i].highlight
					if not highlight:IsShown() then
						highlight.anim:Play()
					end
				else
					self.points[i].highlight:Hide()
				end
			end
		end
	end
end)

combo:RegisterEvent"UNIT_COMBO_POINTS"
combo:RegisterEvent"TARGET_CHANGED"
combo:RegisterEvent"UNIT_ENTERED_VEHICLE"
combo:RegisterEvent"UNIT_EXITED_VEHICLE"

-- action bar(s)
do return end

local function Button_UpdateSpell(self)
	local spell = self.spell
	-- Range or Usable
	local inRange = IsSpellInRange(spell, "target")
	local isUsable, notEnoughMana = IsUsableSpell(spell)
	if not inRange then
		self.icon:SetVertexColor(1.0, 0.0, 0.0)
		self.normalTexture:SetVertexColor(1.0, 0.0, 0.0)
	elseif isUsable then
		self.icon:SetVertexColor(1.0, 1.0, 1.0)
		self.normalTexture:SetVertexColor(1.0, 1.0, 1.0)
	elseif notEnoughMana then
		self.icon:SetVertexColor(0.5, 0.5, 1.0)
		self.normalTexture:SetVertexColor(0.5, 0.5, 1.0)
	else
		self.icon:SetVertexColor(0.4, 0.4, 0.4)
		self.normalTexture:SetVertexColor(1.0, 1.0, 1.0)
	end
	-- Cooldown
	local start, duration, enable = GetSpellCooldown(spell)
	if start then
		CooldownFrame_SetTimer(self.cooldown, start, duration, enable)
	end
	-- State
	self:SetChecked(0)
end

local function Button_UpdateItem(self)
	local slot = self.slot
	-- Range or Usable
	local item = GetInventoryItemLink("player", slot)
	local inRange = IsItemInRange(item, "target")
	local isUsable, notEnoughMana = IsUsableItem(item)
	if not inRange then
		self.icon:SetVertexColor(1.0, 0.0, 0.0)
		self.normalTexture:SetVertexColor(1.0, 0.0, 0.0)
	elseif isUsable then
		self.icon:SetVertexColor(1.0, 1.0, 1.0)
		self.normalTexture:SetVertexColor(1.0, 1.0, 1.0)
	elseif notEnoughMana then
		self.icon:SetVertexColor(0.5, 0.5, 1.0)
		self.normalTexture:SetVertexColor(0.5, 0.5, 1.0)
	else
		self.icon:SetVertexColor(0.4, 0.4, 0.4)
		self.normalTexture:SetVertexColor(1.0, 1.0, 1.0)
	end
	-- Cooldown
	local start, duration, enable = GetInventoryItemCooldown("player", slot)
	if start then
		CooldownFrame_SetTimer(self.cooldown, start, duration, enable)
	end
	-- State
	self:SetChecked(0)
end


local function Button_Set(self, type, ...)
	self:UnregisterEvent"SPELL_UPDATE_COOLDOWN"
	self:UnregisterEvent"SPELL_UPDATE_USABLE"
	if type == "item" then
		local slot = ...
		self.slot = slot
		self:SetAttribute("type", "item")
		self:SetAttribute("item", slot)
		local texture = GetInventoryItemTexture("player", slot)
		self.icon:SetTexture(texture)
		self.Update = Button_UpdateItem
--~ 		self:RegisterEvent""
	elseif type == "spell" then
		local spell = ...
		self.spell = spell
		self:SetAttribute("type", "spell")
		self:SetAttribute("spell", spell)
		local texture = select(3, GetSpellInfo(spell))
		self.icon:SetTexture(texture)
		self.count:Hide()
		self.Update = Button_UpdateSpell
		self:RegisterEvent"SPELL_UPDATE_COOLDOWN"
		self:RegisterEvent"SPELL_UPDATE_USABLE"
	else
		self.icon:SetTexture()
		self:SetAttribute("type", "")
		self.Update = function () end
	end
	self:SetScript("OnEvent", self.Update)
	self:Update()
end

local function Button_Update(self)
	local type = self:GetAttribute"type"
	if type == "item" then
	elseif type == "spell" then
	end
end

local function MakeActionButton(parent, inherit)
	local child

	local button = CreateFrame("CheckButton", nil, parent, inherit)
	button:SetAttribute("*unit2", "player")

	button:SetSize(36, 36)

	child = button:CreateTexture(nil, "BACKGROUND")
	child:SetAllPoints()
	button.icon = child

--~ 	child = button:CreateTexture(nil, "ARTWORK")
--~ 	child:SetTexture"Interface\\Buttons\\UI-QuickslotRed"
--~ 	child:SetAllPoints()
--~ 	button.flash = child

--~ 	child = button:CreateFontString(nil, "ARTWORK")
--~ 	child:SetFontObject(NumberFontNormalSmallGray)
--~ 	child:SetJustifyH"RIGHT"
--~ 	child:SetSize(36, 10)
--~ 	child:SetPoint("TOPLEFT", -2, -2)
--~ 	button.hotkey = child
--~ 	child:Hide()

	child = button:CreateFontString(nil, "ARTWORK")
	child:SetFontObject(NumberFontNormal)
	child:SetJustifyH"RIGHT"
	child:SetPoint("BOTTOMRIGHT", -2, 2)
	button.count = child

--~ 	child = button:CreateFontString(nil, "OVERLAY")
--~ 	child:SetFontObject(GameFontHighlightSmallOutline)
--~ 	child:SetSize(36, 10)
--~ 	child:SetPoint("BOTTOM", 0, 2)
--~ 	button.name = child

--~ 	child = button:CreateTexture(nil, "OVERLAY")
--~ 	child:SetTexture"Interface\\Buttons\\UI-ActionButton-Border"
--~ 	child:SetBlendMode"ADD"
--~ 	child:SetSize(62, 62)
--~ 	child:SetPoint"CENTER"
--~ 	button.border = child
--~ 	child:Hide()

	child = CreateFrame("Cooldown", nil, button)
	child:SetSize(36, 36)
	child:SetPoint("CENTER", 0, -1)
	button.cooldown = child

	child = button:CreateTexture()
	child:SetTexture"Interface\\Buttons\\UI-Quickslot2"
	child:SetSize(66, 66)
	child:SetPoint("CENTER", 0, -1)
	button:SetNormalTexture(child)
	button.normalTexture = child

	child = button:CreateTexture()
	child:SetTexture"Interface\\Buttons\\UI-Quickslot-Depress"
	child:SetAllPoints()
	button:SetPushedTexture(child)

	child = button:CreateTexture()
	child:SetTexture"Interface\\Buttons\\ButtonHilight-Square"
	child:SetBlendMode"ADD"
	child:SetAllPoints()
	button:SetHighlightTexture(child)

	child = button:CreateTexture()
	child:SetTexture"Interface\\Buttons\\CheckButtonHilight"
	child:SetBlendMode"ADD"
	child:SetAllPoints()
	button:SetCheckedTexture(child)

	button.Set = Button_Set
	button:SetScript("OnEvent", Button_OnEvent)

	button:RegisterEvent"PLAYER_ENTERING_WORLD"
	button:RegisterEvent"UPDATE_BINDINGS"

	return button
end

local function MakeActionBar(actions)
	local bar = CreateFrame("Frame", nil, UIParent)

	for index, elements in ipairs(actions) do
		button = MakeActionButton(bar, "SecureActionButtonTemplate")
		button:Set(unpack(elements))
		button:SetPoint("TOPLEFT", bar, "TOPLEFT", (index - 1) * 38, 0)
	end

	bar:SetSize(38*#actions, 38)
	return bar
end

local actions = MakeActionBar{
	{"spell", (GetSpellInfo(23922)) }, -- Shield Slam
	{"spell", (GetSpellInfo( 6572)) }, -- Revenge
	{"spell", (GetSpellInfo(30016)) }, -- Devastate
	{"spell", (GetSpellInfo(46968)) }, -- Shockwave
	{"spell", (GetSpellInfo(12809)) }, -- Concussion Blow
	{"spell", (GetSpellInfo( 2565)) }, -- Shield Block
	{"spell", (GetSpellInfo(   72)) }, -- Shield Bash
	{"spell", (GetSpellInfo(23920)) }, -- Spell Reflection
	{"spell", (GetSpellInfo(  676)) }, -- Disarm
}
actions:SetPoint("TOP", rage, "BOTTOM", 0, -1)
local defenses = MakeActionBar{
	{"spell", (GetSpellInfo(  355)) }, -- Taunt
	{"spell", (GetSpellInfo( 6343)) }, -- Thunder Clap
	{"spell", (GetSpellInfo(   78)) }, -- Heroic Strike
	{"spell", (GetSpellInfo(12975)) }, -- Last Stand
	{"spell", (GetSpellInfo(55694)) }, -- Enraged generation
	{"spell", (GetSpellInfo(  871)) }, -- Shield Wall
	{"spell", (GetSpellInfo( 3411)) }, -- Intervene
	{"item", GetInventorySlotInfo"Trinket0Slot" }, -- Trinket0
	{"item", GetInventorySlotInfo"Trinket1Slot" }, -- Trinket1
}
defenses:SetPoint("TOP", actions, "BOTTOM", 0, -1)

-- bindings
local f = CreateFrame"Frame"
f:SetScript("OnEvent", function (self, event, ...)
	local handler = self[event]
	if handler then handler(self, event, ...) end
end)

f:RegisterEvent"PLAYER_REGEN_ENABLED"
f:RegisterEvent"PLAYER_REGEN_DISABLED"

function f:PLAYER_REGEN_ENABLED()
	ClearOverrideBindings(self)
end

local BINDING_SPELLS = {
	[GetLocale() == "frFR" and "A" or "Q"] = (GetSpellInfo(23922)), -- Shield Slam
	["E"] = (GetSpellInfo(78)), -- Heroic Strike
}

function f:PLAYER_REGEN_DISABLED()
	if GetActiveTalentGroup() == 1 then
		for key, spell in pairs(BINDING_SPELLS) do
			SetOverrideBindingSpell(self, false, key, spell)
		end
	end
end
